import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectEntityManager } from '@nestjs/typeorm';
import { MeetingRoom } from 'src/meeting-room/entities/meeting-room.entity';
import { User } from 'src/user/entities/user.entity';
import { EntityManager, Like } from 'typeorm';
import { Booking } from './entities/booking.entity';
import { ListBookDto } from './dto/list-book.dto';
import { AddBookDto } from './dto/add-book.dto';

@Injectable()
export class BookingService {
  @InjectEntityManager()
  private readonly entityManager: EntityManager;
  async initData() {
    const user1 = await this.entityManager.findOne(User, {
      where: {
        id: 1,
      },
    });
    const user2 = await this.entityManager.findOne(User, {
      where: {
        id: 2,
      },
    });
    const room1 = await this.entityManager.findOne(MeetingRoom, {
      where: {
        id: 1,
      },
    });
    const room2 = await this.entityManager.findOne(MeetingRoom, {
      where: {
        id: 2,
      },
    });
    const booking1 = new Booking();
    booking1.room = room1;
    booking1.user = user1;
    booking1.startTime = new Date();
    booking1.endTime = new Date(Date.now() + 1000 * 60 * 60);
    await this.entityManager.insert(Booking, booking1);
    const booking2 = new Booking();
    booking2.room = room2;
    booking2.user = user2;
    booking2.startTime = new Date();
    booking2.endTime = new Date(Date.now() + 1000 * 60 * 60);
    await this.entityManager.insert(Booking, booking2);
    const booking3 = new Booking();
    booking3.room = room1;
    booking3.user = user2;
    booking3.startTime = new Date();
    booking3.endTime = new Date(Date.now() + 1000 * 60 * 60);

    await this.entityManager.insert(Booking, booking3);

    const booking4 = new Booking();
    booking4.room = room2;
    booking4.user = user1;
    booking4.startTime = new Date();
    booking4.endTime = new Date(Date.now() + 1000 * 60 * 60);

    await this.entityManager.insert(Booking, booking4);
  }
  async list(listBookDto: ListBookDto) {
    const { user = '', room = '' } = listBookDto;
    const skip = listBookDto.pageSize * (listBookDto.pageNo - 1);
    const [bookings, totalCount] = await this.entityManager.findAndCount(
      Booking,
      {
        where: {
          user: {
            username: Like(`%${user}%`),
          },
          room: {
            name: Like(`%${room}%`),
          },
        },
        relations: {
          user: true,
          room: true,
        },
        skip,
        take: listBookDto.pageSize,
      },
    );
    return {
      bookings: bookings.map((v) => {
        delete v.user.password;
        return {
          ...v,
          user: v.user,
        };
      }),
      totalCount,
    };
  }
  async add(addBookDto: AddBookDto) {
    const { user, room, startTime, endTime, note = '' } = addBookDto;
    const foundUser = await this.entityManager.findOne(User, {
      where: {
        username: user,
      },
    });
    const foundRoom = await this.entityManager.findOne(MeetingRoom, {
      where: {
        name: room,
      },
    });
    if (!foundUser) {
      throw new HttpException('用户不存在', HttpStatus.BAD_REQUEST);
    }
    if (!foundRoom) {
      throw new HttpException('会议室不存在', HttpStatus.BAD_REQUEST);
    }
    if (foundRoom.isBooked) {
      throw new HttpException('会议室已被预定', HttpStatus.BAD_REQUEST);
    }

    const booking = new Booking();
    booking.user = foundUser;
    booking.room = foundRoom;
    booking.startTime = startTime;
    booking.endTime = endTime;
    booking.note = note;
    try {
      await this.entityManager.insert(Booking, booking);
      await this.entityManager.update(MeetingRoom, foundRoom.id, {
        isBooked: true,
      });
      return '新增成功';
    } catch (e) {
      throw new HttpException('新增失败', HttpStatus.BAD_REQUEST);
    }
  }
  async deleteById(id: number) {
    const foundBooking = await this.entityManager.findOne(Booking, {
      where: {
        id,
      },
    });
    if (!foundBooking) {
      throw new HttpException('该预定不存在', HttpStatus.BAD_REQUEST);
    }
    try {
      await this.entityManager.delete(Booking, id);
      await this.entityManager.update(MeetingRoom, foundBooking.room.id, {
        isBooked: false,
      });
      return '删除成功';
    } catch (e) {
      throw new HttpException('删除失败', HttpStatus.BAD_REQUEST);
    }
  }
  async updateById(addBookDto: AddBookDto & { id: number }) {
    const { id } = addBookDto;
    const foundBooking = await this.entityManager.findOne(Booking, {
      where: {
        id,
      },
    });
    if (!foundBooking) {
      throw new HttpException('该预定不存在', HttpStatus.BAD_REQUEST);
    }
    foundBooking.note = addBookDto.note;
    foundBooking.startTime = addBookDto.startTime;
    foundBooking.endTime = addBookDto.endTime;
    try {
      await this.entityManager.update(Booking, id, foundBooking);
      return '更新成功';
    } catch (e) {
      throw new HttpException('更新失败', HttpStatus.BAD_REQUEST);
    }
  }
}
